package cn.lanqiao.rbac.interceptor;


import cn.lanqiao.rbac.util.CurrentUserUtil;
import cn.lanqiao.rbac.util.Result;
import cn.lanqiao.vo.UserVO;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 方法执行顺序为 preHandle – Controller 方法 – postHandle – afterCompletion
 * preHandle: 访问controller之前调用
 * postHandle: ModelAndView渲染前调用
 * afterCompletion: 完成请求和响应后调用
 * ps:需要配置config
 * */
@Component
public class LoginInterceptor implements HandlerInterceptor {

    /**
     * 在yaml配置文件中读取秘钥
     * */
    @Value("${cn.lanqiao.key}")
    private String key;

    /**
     * 使用拦截器实现JWT登录验证
     * */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        try {
            //获得token操作
            String token = request.getHeader("Authorization");
            if(token == null){
               return failResult(605,"请先登录！！",response);
            }
            //解密操作
            Algorithm algorithm = Algorithm.HMAC256(key);//设置加密方式
            JWTVerifier jwtVerifier = JWT.require(algorithm).build();//创建认证对象，创建失败会抛出AlgorithmMismatchException异常。
            DecodedJWT decodedJWT = jwtVerifier.verify(token.substring(7));//对去掉头信息的token进行验证
            //后续操作
            UserVO user = new UserVO();
            user.setUserId(decodedJWT.getClaim("userId").asInt());//获得JWT中的用户id
            user.setUserName(decodedJWT.getClaim("userName").asString());//获得JWT中的用户名
            user.setRoleName(decodedJWT.getClaim("roleName").asString());//获得JWT中的角色
            user.setRoleId(decodedJWT.getClaim("roleId").asInt());
            CurrentUserUtil.set(user);
            //鉴权
            String url = "";
            //在数据库role_path获得list<path>   /user/insert  /user/query   /role/

//
//            if(url.startsWith("/user/") && user.getRoleId() == 1){
//
//            }else{
//                return failResult(408,"该用户权限不足！",response);
//            }





            System.out.println(user);
            return true;
        } catch (JWTDecodeException e){
            return failResult(606,"秘钥格式错误！",response);
        } catch (SignatureVerificationException e){
            return failResult(607,"秘钥解密错误！",response);
        } catch (TokenExpiredException e) {
            return failResult(608,"token过期，请重新登录！",response);
        } catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 验证失败统一向前端返回错误结果
     * @param code 错误码
     * @param message 错误信息
     * @param response 响应对象
     * */
    public boolean failResult(int code ,String message, HttpServletResponse response){
        try {
            ObjectMapper objectMapper = new ObjectMapper();//使用jackson，也可以使用fastjson
            response.setStatus(code);
            response.setContentType(MediaType.APPLICATION_JSON_VALUE);
            response.setCharacterEncoding("UTF-8");
            response.getWriter().print( objectMapper.writeValueAsString(Result.error(code,message)));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }
}
